﻿#include "dxstdafx.h"
#include "GuiEditors.h"
#include <fstream>
#include "GuiCommonConfig.h"
#include "Support/GUI/GuiConfigIO.h"
#include "Support/rapidjson/document.h"
#include "Support/rapidjson/prettywriter.h"
#include "Support/rapidjson/stringbuffer.h"
#include "Support/rapidjson/error/en.h"
#include "Support/GUI/GuiBorder.h"

extern CGuiBorder g_UIBorder;
extern CGuiCommonConfig g_GuiCommonConfig;

GuiEditors::GuiEditors()
{
	m_bEditLock = false;
	m_pEditControl = NULL;
}

void GuiEditors::SetEditorsValue(int width, int height, int offsetX, int offsetY)
{
	CString strTemp;
	CDXUTEditBox* pEdit = GetEditBox(EditBox_EditorsWidth);
	if (pEdit)
	{
		strTemp.Format(L"%d", width);
		pEdit->SetText(strTemp);
	}
	pEdit = GetEditBox(EditBox_EditorsHeight);
	if (pEdit)
	{
		strTemp.Format(L"%d", height);
		pEdit->SetText(strTemp);
	}
	pEdit = GetEditBox(EditBox_EditorsOffsetX);
	if (pEdit)
	{
		strTemp.Format(L"%d", offsetX);
		pEdit->SetText(strTemp);
	}
	pEdit = GetEditBox(EditBox_EditorsOffsetY);
	if (pEdit)
	{
		strTemp.Format(L"%d", offsetY);
		pEdit->SetText(strTemp);
	}
}

void GuiEditors::SyncBorder()
{
	if (!m_bEditLock || NULL == m_pEditControl || NULL == m_pEditControl->m_pDialog)
	{
		return;
	}
	POINT ptSize, ptLocation, ptDialogLocation;
	m_pEditControl->GetSize(ptSize);
	m_pEditControl->GetLocation(ptLocation);
	m_pEditControl->m_pDialog->GetLocation(ptDialogLocation);
	g_UIBorder.SetBorder(ptLocation.x + ptDialogLocation.x, ptLocation.y + ptDialogLocation.y, ptSize.x, ptSize.y);
}

void GuiEditors::SaveChangeToGFX()
{
	CHECK_RETURN(m_pEditControl);
	CHECK_RETURN(m_pEditControl->m_pProperty);
	if (!m_bEditLock)
	{
		return;
	}

	std::wstring strEditPath;
	for (const auto &it : g_GuiCommonConfig.m_mapDialog2Gui)
	{
		if (m_pEditControl->m_pProperty->DialogName == it.first)
		{
			strEditPath = it.second;
			break;
		}
	}
	if (strEditPath.empty())
	{
		CString strError("File Path is NULL");
		CommonFunc::ErrorMessageBox(strError);
		return;
	}
	//读Json
	std::wstring szRcPathOut;
	CommonFunc::RelativePath2FullPath(strEditPath, szRcPathOut);
	std::wstring wstrOut = CommonFunc::ReadInputFile(szRcPathOut);
	
	rapidjson::GenericDocument<rapidjson::UTF16<> > readdoc;
	if (readdoc.Parse(wstrOut.c_str()).HasParseError())
	{
		std::wstring wstrTemp = CommonFunc::StringToWString(GetParseError_En(readdoc.GetParseError()));
		CString strError;
		strError.Format(L"Error(%u): %s", (unsigned)readdoc.GetErrorOffset(), wstrTemp.c_str());
		CommonFunc::ErrorMessageBox(strError);
		return;
	}
	// 遍历Json
	// 没有的字段会存在问题
	bool bWalkSuccess = false;
	for (auto iter1 = readdoc.MemberBegin(); !bWalkSuccess && iter1 != readdoc.MemberEnd(); ++iter1)
	{
		if (!(iter1->value).IsObject())
		{
			continue;
		}
		for (auto iter2 = (iter1->value).MemberBegin(); !bWalkSuccess && iter2 != (iter1->value).MemberEnd(); ++iter2)
		{
			if (!(iter2->value).IsObject())
			{
				continue;
			}
			for (auto iter3 = (iter2->value).MemberBegin(); !bWalkSuccess && iter3 != (iter2->value).MemberEnd(); ++iter3)
			{
				if (wcscmp((iter3->name).GetString(), L"id") == 0 && (iter3->value).GetInt() == m_pEditControl->m_pProperty->nID)
				{
					if ((iter2->value).HasMember(L"width"))
					{
						rapidjson::GenericValue<rapidjson::UTF16<> >& JsonWidth = (iter2->value)[L"width"];
						CDXUTEditBox* pEditControl = GetEditBox(EditBox_EditorsWidth);
						if (pEditControl)
						{
							JsonWidth.SetInt(_wtoi(pEditControl->GetText()));
						}
					}
					if ((iter2->value).HasMember(L"height"))
					{
						rapidjson::GenericValue<rapidjson::UTF16<> >& JsonHeight = (iter2->value)[L"height"];
						CDXUTEditBox* pEditControl = GetEditBox(EditBox_EditorsHeight);
						if (pEditControl)
						{
							JsonHeight.SetInt(_wtoi(pEditControl->GetText()));
						}
					}
					if ((iter2->value).HasMember(L"offsetx"))
					{
						rapidjson::GenericValue<rapidjson::UTF16<> >& JsonOffsetX = (iter2->value)[L"offsetx"];
						CDXUTEditBox* pEditControl = GetEditBox(EditBox_EditorsOffsetX);
						if (pEditControl)
						{
							JsonOffsetX.SetInt(_wtoi(pEditControl->GetText()));
						}
					}
					if ((iter2->value).HasMember(L"offsety"))
					{
						rapidjson::GenericValue<rapidjson::UTF16<> >& JsonOffsetY = (iter2->value)[L"offsety"];
						CDXUTEditBox* pEditControl = GetEditBox(EditBox_EditorsOffsetY);
						if (pEditControl)
						{
							JsonOffsetY.SetInt(_wtoi(pEditControl->GetText()));
						}
					}
					bWalkSuccess = true;
					break;
				}
			}
		}
	}
	if (!bWalkSuccess)
	{
		CString strError("There's Extra Fields!");
		CommonFunc::ErrorMessageBox(strError);
		return;
	}
	//写Json
	rapidjson::StringBuffer buffer;
	rapidjson::PrettyWriter<rapidjson::StringBuffer, rapidjson::UTF16<>, rapidjson::UTF16<> > writer(buffer);
	readdoc.Accept(writer);
	std::string result = buffer.GetString();
	std::ofstream fOut;
	fOut.open(szRcPathOut.c_str(), std::ios::trunc);
	fOut.write(result.c_str(), result.length());
}

void GuiEditors::OnEvent(UINT nEvent, int nControlID, CDXUTControl* pControl)
{
	CDXUTEditBox* pEditor = (CDXUTEditBox*)pControl;
	CHECK_RETURN(m_pEditControl);
	CHECK_RETURN(pEditor);

	switch (nEvent)
	{
	case EVENT_BUTTON_CLICKED:
	{
		switch (nControlID)
		{
			case Button_EditorsSave:
			{
				SaveChangeToGFX();
				break;
			}
			default:
				break;
		}
		break;
	}
	case EVENT_EDITBOX_CHANGE:
	{
		if (m_bEditLock)
		{
			int nOut = _wtoi(pEditor->GetText());
			switch (nControlID)
			{
				case EditBox_EditorsWidth:
				{
					if (nOut > 0)
					{
						POINT ptOut;
						m_pEditControl->GetSize(ptOut);
						m_pEditControl->SetSize(nOut, ptOut.y);
					}
					break;
				}
				case EditBox_EditorsHeight:
				{
					if (nOut > 0)
					{
						POINT ptOut;
						m_pEditControl->GetSize(ptOut);
						m_pEditControl->SetSize(ptOut.x, nOut);
					}
					break;
				}
				case EditBox_EditorsOffsetX:
				{
					POINT ptOut;
					m_pEditControl->GetLocation(ptOut);
					m_pEditControl->SetLocation(nOut, ptOut.y);
					break;
				}
				case EditBox_EditorsOffsetY:
				{
					POINT ptOut;
					m_pEditControl->GetLocation(ptOut);
					m_pEditControl->SetLocation(ptOut.x, nOut);
					break;
				}
				default:
					break;
			}
		}
		break;
	}
	default:
		break;
	}
}

bool GuiEditors::MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (nullptr == m_pEditControl || nullptr == m_pEditControl->m_pProperty || !m_bEditLock)
	{
		return false;
	}

	switch (uMsg)
	{
		case WM_KEYDOWN:
		{
			switch (wParam)
			{
				case 'W':
				{
					POINT ptOut;
					m_pEditControl->GetLocation(ptOut);
					m_pEditControl->SetLocation(ptOut.x, ptOut.y - 1);
					CDXUTEditBox* pEditControl = GetEditBox(EditBox_EditorsOffsetY);
					if (pEditControl)
					{
						CString str;
						str.Format(L"%d", ptOut.y - 1);
						pEditControl->SetText(str);
					}
					SyncBorder();
					return true;
				}
				case 'S':
				{
					POINT ptOut;
					m_pEditControl->GetLocation(ptOut);
					m_pEditControl->SetLocation(ptOut.x, ptOut.y + 1);
					CDXUTEditBox* pEditControl = GetEditBox(EditBox_EditorsOffsetY);
					if (pEditControl)
					{
						CString str;
						str.Format(L"%d", ptOut.y + 1);
						pEditControl->SetText(str);
					}
					SyncBorder();
					return true;
				}
				case 'A':
				{
					POINT ptOut;
					m_pEditControl->GetLocation(ptOut);
					m_pEditControl->SetLocation(ptOut.x - 1, ptOut.y);
					CDXUTEditBox* pEditControl = GetEditBox(EditBox_EditorsOffsetX);
					if (pEditControl)
					{
						CString str;
						str.Format(L"%d", ptOut.x - 1);
						pEditControl->SetText(str);
					}
					SyncBorder();
					return true;
				}
				case 'D':
				{
					POINT ptOut;
					m_pEditControl->GetLocation(ptOut);
					m_pEditControl->SetLocation(ptOut.x + 1, ptOut.y);
					CDXUTEditBox* pEditControl = GetEditBox(EditBox_EditorsOffsetX);
					if (pEditControl)
					{
						CString str;
						str.Format(L"%d", ptOut.x + 1);
						pEditControl->SetText(str);
					}
					SyncBorder();
					return true;
				}
				default:
					break;
			}
			break;
		}
		default:
			break;
	}
	return false;
}